package com.jingbit.ai.okhttp;


import com.jingbit.ai.base.BaseApp;
import com.jingbit.ai.helper.FileHelper;
import com.jingbit.ai.okhttp.listener.ICallback;

import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


public class OKHttp {

    private static final String TAG = BaseApp.TAG + ":OKHttp";

    private static OKHttp mInstance;
    private OkHttpClient okHttpClient;

    private OKHttp() {
        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .build();
    }

    /**
     * 获取 OkHttpUtils 实例
     */
    public static OKHttp getInstance() {
        if (mInstance == null) {
            synchronized (OKHttp.class) {
                if (mInstance == null) {
                    mInstance = new OKHttp();
                }
            }
        }
        return mInstance;
    }

    /**
     * GET 请求
     */
    public void get(String url, Map<String, String> params, okhttp3.Callback callback) {
        StringBuilder sb = new StringBuilder(url);
        if (params != null && !params.isEmpty()) {
            sb.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
            sb.deleteCharAt(sb.length() - 1);
        }
        Request request = new Request.Builder()
                .get()
                .url(sb.toString())
                .build();
        okHttpClient.newCall(request).enqueue(callback);
    }

    /**
     * POST 请求
     */
    public void post(String url, Map<String, String> params, okhttp3.Callback callback) {
        FormBody.Builder builder = new FormBody.Builder();
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.add(entry.getKey(), entry.getValue());
            }
        }
        Request request = new Request.Builder()
                .post(builder.build())
                .url(url)
                .build();
        okHttpClient.newCall(request).enqueue(callback);
    }

    /**
     * 上传文件
     */
    public void uploadFile(String url, File file, String fileName, Map<String, String> params, okhttp3.Callback callback) {
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", fileName, RequestBody.create(MediaType.parse("application/octet-stream"), file));
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.addFormDataPart(entry.getKey(), entry.getValue());
            }
        }
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        okHttpClient.newCall(request).enqueue(callback);
    }

    /**
     * 下载文件
     */
    public void downloadFile(String url, String destDir, String fileName, ICallback callback) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                callback.onFailure(e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                File dir = new File(destDir);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                File file = new File(dir, fileName);
                FileOutputStream fos = new FileOutputStream(file);
                byte[] buf = new byte[2048];
                long total = response.body().contentLength();
                long current = 0;
                int len;
                while ((len = response.body().byteStream().read(buf)) != -1) {
                    fos.write(buf, 0, len);
                    current += len;
                    callback.onProgress(total, current);
                }
                fos.flush();
                fos.close();
                response.body().close();
                callback.onSuccess(file.getAbsolutePath());

            }
        });
    }
}